package com.bondar.task5;

import java.util.LinkedList;
import java.util.List;

/**
 * Thread Pool
 */
public class ThreadPool {

	private int numOfThreads;
	private List<Runnable> tasks;
	private ExecutorThread[] executors;
	private boolean run = false;

	public ThreadPool(int numOfThreads) {
		this.numOfThreads = numOfThreads;
		this.tasks = new LinkedList<Runnable>();
		this.executors = new ExecutorThread[this.numOfThreads];

		for (int i = 0; i < executors.length; i++) {
			executors[i] = new ExecutorThread();
		}
	}

	/**
	 * Add new task to pool queue
	 * 
	 * @param runnable
	 */
	public void execute(Runnable runnable) {
		synchronized (tasks) {
			tasks.add(runnable);
			tasks.notify();
		}
		
		if (!run) {
			for (ExecutorThread executorThread : executors) {
				executorThread.start();
			}
			run = true;
		}
	}

	private class ExecutorThread extends Thread {
		@Override
		public void run() {
			Runnable task = null;
			while (!isInterrupted()) {
				
				synchronized (tasks) {
					if ( tasks.isEmpty() ) {
						try {
							tasks.wait();
						} catch (InterruptedException e) {}
					}
					task = tasks.remove(tasks.size()-1);
				}
					
				task.run();
			}
		}

	}
}
